home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / AlgoWaveTableWindow.c < prev    next >
Text File  |  1994-12-28  |  32KB  |  1,023 lines

  1. /* AlgoWaveTableWindow.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "AlgoWaveTableWindow.h"
  31. #include "MainWindowStuff.h"
  32. #include "AlgoWaveTableObject.h"
  33. #include "AlgoWaveTableList.h"
  34. #include "TextEdit.h"
  35. #include "IconButton.h"
  36. #include "WindowDispatcher.h"
  37. #include "Memory.h"
  38. #include "Alert.h"
  39. #include "Numbers.h"
  40. #include "GrowIcon.h"
  41. #include "DataMunging.h"
  42. #include "Main.h"
  43. #include "EditImages.h"
  44. #include "FindDialog.h"
  45. #include "WaveTableSizeDialog.h"
  46. #include "GlobalWindowMenuList.h"
  47.  
  48.  
  49. #define WINSIZEX (490)
  50. #define WINSIZEY (300)
  51. #define TITLEINDENT (8)
  52.  
  53. #define NAMEEDITX (80)
  54. #define NAMEEDITY (1)
  55. #define NAMEEDITWIDTH (80)
  56. #define NAMEEDITHEIGHT (19)
  57.  
  58. #define NUMFRAMESEDITX (240)
  59. #define NUMFRAMESEDITY (1)
  60. #define NUMFRAMESEDITWIDTH (80)
  61. #define NUMFRAMESEDITHEIGHT (19)
  62.  
  63. #define NUMTABLESEDITX (400)
  64. #define NUMTABLESEDITY (1)
  65. #define NUMTABLESEDITWIDTH (80)
  66. #define NUMTABLESEDITHEIGHT (19)
  67.  
  68. #define BITS8X (10)
  69. #define BITS8Y (NUMFRAMESEDITY + NUMFRAMESEDITHEIGHT + 4)
  70. #define BITS8WIDTH (32)
  71. #define BITS8HEIGHT (32)
  72.  
  73. #define BITS16X (BITS8X + BITS8WIDTH + 1)
  74. #define BITS16Y (BITS8Y)
  75. #define BITS16WIDTH (BITS8WIDTH)
  76. #define BITS16HEIGHT (BITS8HEIGHT)
  77.  
  78. #define NAMEX (3)
  79. #define NAMEY (4)
  80.  
  81. #define NUMFRAMESX (170)
  82. #define NUMFRAMESY (4)
  83.  
  84. #define NUMTABLESX (330)
  85. #define NUMTABLESY (4)
  86.  
  87. #define FUNCTIONEDITX (-1)
  88. #define FUNCTIONEDITY (BITS16Y + BITS16HEIGHT + 4)
  89. #define FUNCTIONEDITWIDTH(Width) ((Width) + 2)
  90. #define FUNCTIONEDITHEIGHT(Height) ((Height) - FUNCTIONEDITY + 1)
  91.  
  92.  
  93. struct AlgoWaveTableWindowRec
  94.     {
  95.         MainWindowRec*                    MainWindow;
  96.         AlgoWaveTableObjectRec*    AlgoWaveTableObject;
  97.         AlgoWaveTableListRec*        AlgoWaveTableList;
  98.  
  99.         WinType*                                ScreenID;
  100.         TextEditRec*                        NameEdit;
  101.         TextEditRec*                        FunctionEdit;
  102.         TextEditRec*                        NumFramesEdit;
  103.         TextEditRec*                        NumTablesEdit;
  104.         TextEditRec*                        ActiveTextEdit;
  105.         IconButtonRec*                    Bits8Button;
  106.         IconButtonRec*                    Bits16Button;
  107.         MyBoolean                                BitsChanged;
  108.         GenericWindowRec*                MyGenericWindow; /* how the window event dispatcher knows us */
  109.         MenuItemType*                        MyMenuItem;
  110.     };
  111.  
  112.  
  113. /* create a new algorithmic wave table editing window */
  114. AlgoWaveTableWindowRec*    NewAlgoWaveTableWindow(struct MainWindowRec* MainWindow,
  115.                                             struct AlgoWaveTableObjectRec* AlgoWaveTableObject,
  116.                                             struct AlgoWaveTableListRec* AlgoWaveTableList,
  117.                                             OrdType WinX, OrdType WinY, OrdType WinWidth, OrdType WinHeight)
  118.     {
  119.         AlgoWaveTableWindowRec*    Window;
  120.         char*                                        StringTemp;
  121.  
  122.         /* deal with window placement */
  123.         if ((WinWidth < 100) || (WinHeight < 100) || ((eOptionKey & CheckModifiers()) != 0))
  124.             {
  125.                 WinX = 20 + WindowOtherEdgeWidths(eDocumentWindow);
  126.                 WinY = 20 + WindowTitleBarHeight(eDocumentWindow);
  127.                 WinWidth = WINSIZEX;
  128.                 WinHeight = WINSIZEY;
  129.             }
  130.         MakeWindowFitOnScreen(&WinX,&WinY,&WinWidth,&WinHeight);
  131.  
  132.         Window = (AlgoWaveTableWindowRec*)AllocPtrCanFail(
  133.             sizeof(AlgoWaveTableWindowRec),"AlgoWaveTableWindowRec");
  134.         if (Window == NIL)
  135.             {
  136.              FailurePoint1:
  137.                 AlertHalt("There is not enough memory available to display the algorithmic "
  138.                     "wave table editor.",NIL);
  139.                 return NIL;
  140.             }
  141.         Window->MainWindow = MainWindow;
  142.         Window->AlgoWaveTableObject = AlgoWaveTableObject;
  143.         Window->AlgoWaveTableList = AlgoWaveTableList;
  144.         Window->BitsChanged = False;
  145.  
  146.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  147.             eWindowZoomable,eWindowResizable,WinX,WinY,WinWidth,WinHeight,
  148.             (void (*)(void*))&AlgoWaveTableWindowUpdator,Window);
  149.         if (Window->ScreenID == 0)
  150.             {
  151.              FailurePoint2:
  152.                 ReleasePtr((char*)Window);
  153.                 goto FailurePoint1;
  154.             }
  155.  
  156.         /* create name edit */
  157.         Window->NameEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
  158.             GetScreenFont(),9,NAMEEDITX,NAMEEDITY,NAMEEDITWIDTH,NAMEEDITHEIGHT);
  159.         if (Window->NameEdit == NIL)
  160.             {
  161.              FailurePoint3:
  162.                 KillWindow(Window->ScreenID);
  163.                 goto FailurePoint2;
  164.             }
  165.         /* install new text in name edit */
  166.         StringTemp = AlgoWaveTableObjectGetNameCopy(AlgoWaveTableObject);
  167.         if (StringTemp == NIL)
  168.             {
  169.              FailurePoint4:
  170.                 DisposeTextEdit(Window->NameEdit);
  171.                 goto FailurePoint3;
  172.             }
  173.         TextEditNewRawData(Window->NameEdit,StringTemp,"\x0a");
  174.         ReleasePtr(StringTemp);
  175.         TextEditHasBeenSaved(Window->NameEdit);
  176.  
  177.         /* create function edit */
  178.         Window->FunctionEdit = NewTextEdit(Window->ScreenID,
  179.             (TEScrollType)(eTEVScrollBar | eTEHScrollBar),GetMonospacedFont(),9,
  180.             FUNCTIONEDITX,FUNCTIONEDITY + GetFontHeight(GetScreenFont(),9),
  181.             FUNCTIONEDITWIDTH(WinWidth),
  182.             FUNCTIONEDITHEIGHT(WinHeight) - GetFontHeight(GetScreenFont(),9));
  183.         if (Window->FunctionEdit == NIL)
  184.             {
  185.              FailurePoint5:
  186.                 goto FailurePoint4;
  187.             }
  188.         SetTextEditTabSize(Window->FunctionEdit,MainWindowGetTabSize(MainWindow));
  189.         StringTemp = AlgoWaveTableObjectGetFormulaCopy(AlgoWaveTableObject);
  190.         if (StringTemp == NIL)
  191.             {
  192.              FailurePoint6:
  193.                 DisposeTextEdit(Window->FunctionEdit);
  194.                 goto FailurePoint5;
  195.             }
  196.         TextEditNewRawData(Window->FunctionEdit,StringTemp,"\x0a");
  197.         ReleasePtr(StringTemp);
  198.         TextEditHasBeenSaved(Window->FunctionEdit);
  199.         SetTextEditAutoIndent(Window->FunctionEdit,True);
  200.  
  201.         Window->NumFramesEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
  202.             GetScreenFont(),9,NUMFRAMESEDITX,NUMFRAMESEDITY,NUMFRAMESEDITWIDTH,NUMFRAMESEDITHEIGHT);
  203.         if (Window->NumFramesEdit == NIL)
  204.             {
  205.              FailurePoint7:
  206.                 goto FailurePoint6;
  207.             }
  208.         StringTemp = IntegerToString(AlgoWaveTableObjectGetNumFrames(AlgoWaveTableObject));
  209.         if (StringTemp == NIL)
  210.             {
  211.              FailurePoint8:
  212.                 DisposeTextEdit(Window->NumFramesEdit);
  213.                 goto FailurePoint7;
  214.             }
  215.         TextEditNewRawData(Window->NumFramesEdit,StringTemp,"\x0a");
  216.         ReleasePtr(StringTemp);
  217.         TextEditHasBeenSaved(Window->NumFramesEdit);
  218.  
  219.         Window->NumTablesEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
  220.             GetScreenFont(),9,NUMTABLESEDITX,NUMTABLESEDITY,NUMTABLESEDITWIDTH,NUMTABLESEDITHEIGHT);
  221.         if (Window->NumTablesEdit == NIL)
  222.             {
  223.              FailurePoint9:
  224.                 goto FailurePoint8;
  225.             }
  226.         StringTemp = IntegerToString(AlgoWaveTableObjectGetNumTables(AlgoWaveTableObject));
  227.         if (StringTemp == NIL)
  228.             {
  229.              FailurePoint10:
  230.                 DisposeTextEdit(Window->NumTablesEdit);
  231.                 goto FailurePoint9;
  232.             }
  233.         TextEditNewRawData(Window->NumTablesEdit,StringTemp,"\x0a");
  234.         ReleasePtr(StringTemp);
  235.         TextEditHasBeenSaved(Window->NumTablesEdit);
  236.  
  237.         Window->Bits8Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS8X,BITS8Y,
  238.             BITS8WIDTH,BITS8HEIGHT,Bits8Unselected,Bits8MouseDown,Bits8Selected,Bits8Selected,
  239.             eIconRadioMode);
  240.         if (Window->Bits8Button == NIL)
  241.             {
  242.              FailurePoint11:
  243.                 goto FailurePoint10;
  244.             }
  245.         Window->Bits16Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS16X,BITS16Y,
  246.             BITS16WIDTH,BITS16HEIGHT,Bits16Unselected,Bits16MouseDown,Bits16Selected,
  247.             Bits16Selected,eIconRadioMode);
  248.         if (Window->Bits16Button == NIL)
  249.             {
  250.              FailurePoint12:
  251.                 DisposeIconButton(Window->Bits8Button);
  252.                 goto FailurePoint11;
  253.             }
  254.         switch (AlgoWaveTableObjectGetNumBits(AlgoWaveTableObject))
  255.             {
  256.                 case eSample16bit:
  257.                     SetIconButtonState(Window->Bits16Button,True);
  258.                     break;
  259.                 case eSample8bit:
  260.                     SetIconButtonState(Window->Bits8Button,True);
  261.                     break;
  262.                 default:
  263.                     EXECUTE(PRERR(ForceAbort,"NewAlgoWaveTableWindow:  bad num bits"));
  264.                     break;
  265.             }
  266.  
  267.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  268.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&AlgoWaveTableWindowDoIdle,
  269.             (void (*)(void*))&AlgoWaveTableWindowBecomeActive,
  270.             (void (*)(void*))&AlgoWaveTableWindowBecomeInactive,
  271.             (void (*)(void*))&AlgoWaveTableWindowJustResized,
  272.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&AlgoWaveTableWindowDoMouseDown,
  273.             (void (*)(unsigned char,ModifierFlags,void*))&AlgoWaveTableWindowDoKeyDown,
  274.             (void (*)(void*))&AlgoWaveTableWindowClose,
  275.             (void (*)(void*))&AlgoWaveTableWindowMenuSetup,
  276.             (void (*)(void*,MenuItemType*))&AlgoWaveTableWindowDoMenuCommand);
  277.         if (Window->MyGenericWindow == NIL)
  278.             {
  279.              FailurePoint13:
  280.                 DisposeIconButton(Window->Bits16Button);
  281.                 goto FailurePoint12;
  282.             }
  283.  
  284.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
  285.         if (Window->MyMenuItem == NIL)
  286.             {
  287.              FailurePoint14:
  288.                 CheckOutDyingWindow(Window->MyGenericWindow);
  289.                 goto FailurePoint13;
  290.             }
  291.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  292.             Window->ScreenID))
  293.             {
  294.              FailurePoint15:
  295.                 KillMenuItem(Window->MyMenuItem);
  296.                 goto FailurePoint14;
  297.             }
  298.  
  299.         Window->ActiveTextEdit = Window->FunctionEdit;
  300.         AlgoWaveTableWindowResetTitlebar(Window);
  301.  
  302.         return Window;
  303.     }
  304.  
  305.  
  306. /* write data back to the object and dispose of the window */
  307. void                                DisposeAlgoWaveTableWindow(AlgoWaveTableWindowRec* Window)
  308.     {
  309.         CheckPtrExistence(Window);
  310.  
  311.         /* save the data */
  312.         if (!AlgoWaveTableWindowWritebackModifiedData(Window))
  313.             {
  314.                 /* failed -- now what? */
  315.             }
  316.  
  317.         AlgoWaveTableObjectClosingWindowNotify(Window->AlgoWaveTableObject,
  318.             GetWindowXStart(Window->ScreenID),GetWindowYStart(Window->ScreenID),
  319.             GetWindowWidth(Window->ScreenID),GetWindowHeight(Window->ScreenID));
  320.         DeregisterWindowMenuItem(Window->MyMenuItem);
  321.         KillMenuItem(Window->MyMenuItem);
  322.         CheckOutDyingWindow(Window->MyGenericWindow);
  323.         DisposeTextEdit(Window->NameEdit);
  324.         DisposeTextEdit(Window->FunctionEdit);
  325.         DisposeTextEdit(Window->NumFramesEdit);
  326.         DisposeTextEdit(Window->NumTablesEdit);
  327.         DisposeIconButton(Window->Bits16Button);
  328.         DisposeIconButton(Window->Bits8Button);
  329.         KillWindow(Window->ScreenID);
  330.         ReleasePtr((char*)Window);
  331.     }
  332.  
  333.  
  334. /* find out if the wave table has been modified since the last file save */
  335. MyBoolean                        HasAlgoWaveTableWindowBeenModified(AlgoWaveTableWindowRec* Window)
  336.     {
  337.         CheckPtrExistence(Window);
  338.         return Window->BitsChanged
  339.             || TextEditDoesItNeedToBeSaved(Window->NameEdit)
  340.             || TextEditDoesItNeedToBeSaved(Window->FunctionEdit)
  341.             || TextEditDoesItNeedToBeSaved(Window->NumFramesEdit)
  342.             || TextEditDoesItNeedToBeSaved(Window->NumTablesEdit);
  343.     }
  344.  
  345.  
  346. /* highlight a line in the formula edit box */
  347. void                                AlgoWaveTableWindowHiliteLine(AlgoWaveTableWindowRec* Window,
  348.                                             long LineNumber)
  349.     {
  350.         CheckPtrExistence(Window);
  351.         if (Window->ActiveTextEdit != Window->FunctionEdit)
  352.             {
  353.                 DisableTextEditSelection(Window->ActiveTextEdit);
  354.                 Window->ActiveTextEdit = Window->FunctionEdit;
  355.                 EnableTextEditSelection(Window->ActiveTextEdit);
  356.             }
  357.         SetTextEditSelection(Window->FunctionEdit,LineNumber,0,LineNumber + 1,0);
  358.         TextEditShowSelection(Window->FunctionEdit);
  359.     }
  360.  
  361.  
  362. /* bring the window to the top and give it the focus */
  363. void                                AlgoWaveTableWindowBringToTop(AlgoWaveTableWindowRec* Window)
  364.     {
  365.         CheckPtrExistence(Window);
  366.         ActivateThisWindow(Window->ScreenID);
  367.     }
  368.  
  369.  
  370. void                                AlgoWaveTableWindowDoIdle(AlgoWaveTableWindowRec* Window,
  371.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  372.                                             ModifierFlags Modifiers)
  373.     {
  374.         CheckPtrExistence(Window);
  375.         TextEditUpdateCursor(Window->ActiveTextEdit);
  376.         if (CheckCursorFlag)
  377.             {
  378.                 if (TextEditIBeamTest(Window->NameEdit,XLoc,YLoc)
  379.                     || TextEditIBeamTest(Window->FunctionEdit,XLoc,YLoc)
  380.                     || TextEditIBeamTest(Window->NumFramesEdit,XLoc,YLoc)
  381.                     || TextEditIBeamTest(Window->NumTablesEdit,XLoc,YLoc))
  382.                     {
  383.                         SetIBeamCursor();
  384.                     }
  385.                  else
  386.                     {
  387.                         SetArrowCursor();
  388.                     }
  389.             }
  390.     }
  391.  
  392.  
  393. void                                AlgoWaveTableWindowBecomeActive(AlgoWaveTableWindowRec* Window)
  394.     {
  395.         OrdType                        XSize;
  396.         OrdType                        YSize;
  397.  
  398.         CheckPtrExistence(Window);
  399.         EnableTextEditSelection(Window->ActiveTextEdit);
  400.         XSize = GetWindowWidth(Window->ScreenID);
  401.         YSize = GetWindowHeight(Window->ScreenID);
  402.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  403.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  404.     }
  405.  
  406.  
  407. void                                AlgoWaveTableWindowBecomeInactive(AlgoWaveTableWindowRec* Window)
  408.     {
  409.         OrdType                        XSize;
  410.         OrdType                        YSize;
  411.  
  412.         CheckPtrExistence(Window);
  413.         DisableTextEditSelection(Window->ActiveTextEdit);
  414.         XSize = GetWindowWidth(Window->ScreenID);
  415.         YSize = GetWindowHeight(Window->ScreenID);
  416.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  417.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  418.     }
  419.  
  420.  
  421. void                                AlgoWaveTableWindowJustResized(AlgoWaveTableWindowRec* Window)
  422.     {
  423.         OrdType                        XSize;
  424.         OrdType                        YSize;
  425.         OrdType                        FontHeight;
  426.  
  427.         CheckPtrExistence(Window);
  428.         XSize = GetWindowWidth(Window->ScreenID);
  429.         YSize = GetWindowHeight(Window->ScreenID);
  430.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  431.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  432.         FontHeight = GetFontHeight(GetScreenFont(),9);
  433.         SetTextEditPosition(Window->FunctionEdit,FUNCTIONEDITX,FUNCTIONEDITY + FontHeight,
  434.             FUNCTIONEDITWIDTH(XSize),FUNCTIONEDITHEIGHT(YSize) - FontHeight);
  435.     }
  436.  
  437.  
  438. void                                AlgoWaveTableWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  439.                                             ModifierFlags Modifiers, AlgoWaveTableWindowRec* Window)
  440.     {
  441.         CheckPtrExistence(Window);
  442.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  443.             && (XLoc < GetWindowWidth(Window->ScreenID))
  444.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  445.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  446.             {
  447.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  448.                 AlgoWaveTableWindowJustResized(Window);
  449.             }
  450.         else if (TextEditHitTest(Window->NameEdit,XLoc,YLoc))
  451.             {
  452.                 if (Window->ActiveTextEdit != Window->NameEdit)
  453.                     {
  454.                         DisableTextEditSelection(Window->ActiveTextEdit);
  455.                         Window->ActiveTextEdit = Window->NameEdit;
  456.                         EnableTextEditSelection(Window->ActiveTextEdit);
  457.                     }
  458.                 TextEditDoMouseDown(Window->NameEdit,XLoc,YLoc,Modifiers);
  459.             }
  460.         else if (TextEditHitTest(Window->FunctionEdit,XLoc,YLoc))
  461.             {
  462.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  463.                     {
  464.                         DisableTextEditSelection(Window->ActiveTextEdit);
  465.                         Window->ActiveTextEdit = Window->FunctionEdit;
  466.                         EnableTextEditSelection(Window->ActiveTextEdit);
  467.                     }
  468.                 TextEditDoMouseDown(Window->FunctionEdit,XLoc,YLoc,Modifiers);
  469.             }
  470.         else if (TextEditHitTest(Window->NumFramesEdit,XLoc,YLoc))
  471.             {
  472.                 long                            OldNumFrames;
  473.                 long                            NewNumFrames;
  474.                 char*                            NewStringTemp;
  475.  
  476.                 OldNumFrames = AlgoWaveTableWindowGetNumFrames(Window);
  477.                 NewNumFrames = AskForNewWaveTableSize(OldNumFrames);
  478.                 NewStringTemp = IntegerToString(NewNumFrames);
  479.                 if (NewStringTemp != NIL)
  480.                     {
  481.                         TextEditNewRawData(Window->NumFramesEdit,NewStringTemp,"\x0a");
  482.                         ReleasePtr(NewStringTemp);
  483.                     }
  484.             }
  485.         else if (TextEditHitTest(Window->NumTablesEdit,XLoc,YLoc))
  486.             {
  487.                 if (Window->ActiveTextEdit != Window->NumTablesEdit)
  488.                     {
  489.                         DisableTextEditSelection(Window->ActiveTextEdit);
  490.                         Window->ActiveTextEdit = Window->NumTablesEdit;
  491.                         EnableTextEditSelection(Window->ActiveTextEdit);
  492.                     }
  493.                 TextEditDoMouseDown(Window->NumTablesEdit,XLoc,YLoc,Modifiers);
  494.             }
  495.         else if (IconButtonHitTest(Window->Bits8Button,XLoc,YLoc))
  496.             {
  497.                 if (IconButtonMouseDown(Window->Bits8Button,XLoc,YLoc,NIL,NIL))
  498.                     {
  499.                         Window->BitsChanged = True;
  500.                         SetIconButtonState(Window->Bits16Button,False);
  501.                     }
  502.             }
  503.         else if (IconButtonHitTest(Window->Bits16Button,XLoc,YLoc))
  504.             {
  505.                 if (IconButtonMouseDown(Window->Bits16Button,XLoc,YLoc,NIL,NIL))
  506.                     {
  507.                         Window->BitsChanged = True;
  508.                         SetIconButtonState(Window->Bits8Button,False);
  509.                     }
  510.             }
  511.     }
  512.  
  513.  
  514. void                                AlgoWaveTableWindowDoKeyDown(unsigned char KeyCode,
  515.                                             ModifierFlags Modifiers,AlgoWaveTableWindowRec* Window)
  516.     {
  517.         CheckPtrExistence(Window);
  518.         TextEditDoKeyPressed(Window->ActiveTextEdit,KeyCode,Modifiers);
  519.     }
  520.  
  521.  
  522. void                                AlgoWaveTableWindowClose(AlgoWaveTableWindowRec* Window)
  523.     {
  524.         CheckPtrExistence(Window);
  525.         DisposeAlgoWaveTableWindow(Window);
  526.     }
  527.  
  528.  
  529. void                                AlgoWaveTableWindowUpdator(AlgoWaveTableWindowRec* Window)
  530.     {
  531.         OrdType                        XSize;
  532.         OrdType                        YSize;
  533.         FontType                    ScreenFont;
  534.  
  535.         CheckPtrExistence(Window);
  536.         ScreenFont = GetScreenFont();
  537.         TextEditFullRedraw(Window->NameEdit);
  538.         TextEditFullRedraw(Window->FunctionEdit);
  539.         TextEditFullRedraw(Window->NumFramesEdit);
  540.         TextEditFullRedraw(Window->NumTablesEdit);
  541.         RedrawIconButton(Window->Bits16Button);
  542.         RedrawIconButton(Window->Bits8Button);
  543.         XSize = GetWindowWidth(Window->ScreenID);
  544.         YSize = GetWindowHeight(Window->ScreenID);
  545.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  546.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Name:",5,NAMEX,NAMEY,ePlain);
  547.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Num Tables:",11,
  548.             NUMTABLESX,NUMTABLESY,ePlain);
  549.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Num Frames:",11,
  550.             NUMFRAMESX,NUMFRAMESY,ePlain);
  551.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Waveform Generating Function:",29,
  552.             FUNCTIONEDITX + TITLEINDENT,FUNCTIONEDITY,eBold);
  553.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  554.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  555.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  556.     }
  557.  
  558.  
  559. void                                AlgoWaveTableWindowMenuSetup(AlgoWaveTableWindowRec* Window)
  560.     {
  561.         CheckPtrExistence(Window);
  562.         MainWindowEnableGlobalMenus(Window->MainWindow);
  563.         EnableMenuItem(mPaste);
  564.         ChangeItemName(mPaste,"Paste Text");
  565.         if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  566.             {
  567.                 EnableMenuItem(mCut);
  568.                 ChangeItemName(mCut,"Cut Text");
  569.                 EnableMenuItem(mCopy);
  570.                 ChangeItemName(mCopy,"Copy Text");
  571.                 EnableMenuItem(mClear);
  572.                 ChangeItemName(mClear,"Clear Text");
  573.             }
  574.         EnableMenuItem(mShiftLeft);
  575.         EnableMenuItem(mShiftRight);
  576.         EnableMenuItem(mBalanceParens);
  577.         EnableMenuItem(mSelectAll);
  578.         ChangeItemName(mSelectAll,"Select All Text");
  579.         if (TextEditCanWeUndo(Window->ActiveTextEdit))
  580.             {
  581.                 EnableMenuItem(mUndo);
  582.                 ChangeItemName(mUndo,"Undo Text Change");
  583.             }
  584.         ChangeItemName(mCloseFile,"Close Algorithmic Wave Table Editor");
  585.         EnableMenuItem(mCloseFile);
  586.         ChangeItemName(mBuildFunction,"Build Wave Table");
  587.         EnableMenuItem(mBuildFunction);
  588.         ChangeItemName(mUnbuildFunction,"Unbuild Wave Table");
  589.         EnableMenuItem(mUnbuildFunction);
  590.         ChangeItemName(mAlgoSampToSample,"Open Algorithmic Wave Table As New Wave Table");
  591.         EnableMenuItem(mAlgoSampToSample);
  592.         ChangeItemName(mDeleteObject,"Delete Algorithmic Wave Table");
  593.         EnableMenuItem(mDeleteObject);
  594.         EnableMenuItem(mFind);
  595.         if (PtrSize(GlobalSearchString) != 0)
  596.             {
  597.                 EnableMenuItem(mFindAgain);
  598.                 if ((Window->ActiveTextEdit != NIL)
  599.                     && TextEditIsThereValidSelection(Window->ActiveTextEdit))
  600.                     {
  601.                         EnableMenuItem(mReplace);
  602.                         EnableMenuItem(mReplaceAndFindAgain);
  603.                     }
  604.             }
  605.         EnableMenuItem(mShowSelection);
  606.         if ((Window->ActiveTextEdit != NIL)
  607.             && TextEditIsThereValidSelection(Window->ActiveTextEdit))
  608.             {
  609.                 EnableMenuItem(mEnterSelection);
  610.             }
  611.         SetItemCheckmark(Window->MyMenuItem);
  612.     }
  613.  
  614.  
  615. void                                AlgoWaveTableWindowDoMenuCommand(AlgoWaveTableWindowRec* Window,
  616.                                             MenuItemType* MenuItem)
  617.     {
  618.         CheckPtrExistence(Window);
  619.         if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
  620.             {
  621.             }
  622.         else if (MenuItem == mPaste)
  623.             {
  624.                 TextEditDoMenuPaste(Window->ActiveTextEdit);
  625.             }
  626.         else if (MenuItem == mCut)
  627.             {
  628.                 TextEditDoMenuCut(Window->ActiveTextEdit);
  629.             }
  630.         else if (MenuItem == mCopy)
  631.             {
  632.                 TextEditDoMenuCopy(Window->ActiveTextEdit);
  633.             }
  634.         else if (MenuItem == mClear)
  635.             {
  636.                 TextEditDoMenuClear(Window->ActiveTextEdit);
  637.             }
  638.         else if (MenuItem == mSelectAll)
  639.             {
  640.                 TextEditDoMenuSelectAll(Window->ActiveTextEdit);
  641.             }
  642.         else if (MenuItem == mUndo)
  643.             {
  644.                 TextEditDoMenuUndo(Window->ActiveTextEdit);
  645.             }
  646.         else if (MenuItem == mCloseFile)
  647.             {
  648.                 AlgoWaveTableWindowClose(Window);
  649.             }
  650.         else if (MenuItem == mShiftLeft)
  651.             {
  652.                 TextEditShiftSelectionLeftOneTab(Window->ActiveTextEdit);
  653.             }
  654.         else if (MenuItem == mShiftRight)
  655.             {
  656.                 TextEditShiftSelectionRightOneTab(Window->ActiveTextEdit);
  657.             }
  658.         else if (MenuItem == mBalanceParens)
  659.             {
  660.                 TextEditBalanceParens(Window->ActiveTextEdit);
  661.             }
  662.         else if (MenuItem == mBuildFunction)
  663.             {
  664.                 AlgoWaveTableObjectBuild(Window->AlgoWaveTableObject);
  665.             }
  666.         else if (MenuItem == mUnbuildFunction)
  667.             {
  668.                 AlgoWaveTableObjectUnbuild(Window->AlgoWaveTableObject);
  669.             }
  670.         else if (MenuItem == mAlgoSampToSample)
  671.             {
  672.                 if (AlgoWaveTableObjectMakeUpToDate(Window->AlgoWaveTableObject))
  673.                     {
  674.                         char*                    Buffer;
  675.                         long                    NumTables;
  676.                         long                    SliceSize;
  677.                         long                    BytesPerSlice;
  678.  
  679.                         NumTables = AlgoWaveTableObjectGetNumTables(Window->AlgoWaveTableObject);
  680.                         SliceSize = AlgoWaveTableObjectGetNumFrames(Window->AlgoWaveTableObject);
  681.                         BytesPerSlice = SliceSize;
  682.                         if (eSample16bit == AlgoWaveTableObjectGetNumBits(Window->AlgoWaveTableObject))
  683.                             {
  684.                                 BytesPerSlice *= 2;
  685.                             }
  686.                         Buffer = AllocPtrCanFail(BytesPerSlice * NumTables,"AlgoWaveTableTemp");
  687.                         if (Buffer == NIL)
  688.                             {
  689.                                 AlertHalt("There is not enough memory to convert the wave table.",NIL);
  690.                             }
  691.                          else
  692.                             {
  693.                                 long                    Scan;
  694.  
  695.                                 for (Scan = 0; Scan < NumTables; Scan += 1)
  696.                                     {
  697.                                         char*                    OneSlice;
  698.  
  699.                                         OneSlice = AlgoWaveTableObjectGetRawSlice(
  700.                                             Window->AlgoWaveTableObject,Scan);
  701.                                         PRNGCHK(Buffer,&(Buffer[Scan * BytesPerSlice]),BytesPerSlice);
  702.                                         CopyData(OneSlice,&(Buffer[Scan * BytesPerSlice]),BytesPerSlice);
  703.                                     }
  704.                                 MainWindowCopyRawWaveTableAndOpen(Window->MainWindow,Buffer,
  705.                                     AlgoWaveTableObjectGetNumBits(Window->AlgoWaveTableObject),
  706.                                     NumTables,SliceSize);
  707.                                 ReleasePtr(Buffer);
  708.                             }
  709.                     }
  710.             }
  711.         else if (MenuItem == mDeleteObject)
  712.             {
  713.                 AlgoWaveTableListDeleteAlgoWaveTable(Window->AlgoWaveTableList,
  714.                     Window->AlgoWaveTableObject);
  715.             }
  716.         else if (MenuItem == mFind)
  717.             {
  718.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  719.                     {
  720.                         DisableTextEditSelection(Window->ActiveTextEdit);
  721.                         Window->ActiveTextEdit = Window->FunctionEdit;
  722.                         EnableTextEditSelection(Window->ActiveTextEdit);
  723.                     }
  724.                 switch (DoFindDialog(&GlobalSearchString,&GlobalReplaceString,
  725.                     mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
  726.                     {
  727.                         default:
  728.                             EXECUTE(PRERR(ForceAbort,
  729.                                 "AlgoWaveTableWindowDoMenuCommand:  bad value from DoFindDialog"));
  730.                             break;
  731.                         case eFindCancel:
  732.                         case eDontFind:
  733.                             break;
  734.                         case eFindFromStart:
  735.                             SetTextEditInsertionPoint(Window->ActiveTextEdit,0,0);
  736.                             TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  737.                             TextEditShowSelection(Window->ActiveTextEdit);
  738.                             break;
  739.                         case eFindAgain:
  740.                             TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  741.                             TextEditShowSelection(Window->ActiveTextEdit);
  742.                             break;
  743.                     }
  744.             }
  745.         else if (MenuItem == mFindAgain)
  746.             {
  747.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  748.                     {
  749.                         DisableTextEditSelection(Window->ActiveTextEdit);
  750.                         Window->ActiveTextEdit = Window->FunctionEdit;
  751.                         EnableTextEditSelection(Window->ActiveTextEdit);
  752.                     }
  753.                 TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  754.                 TextEditShowSelection(Window->ActiveTextEdit);
  755.             }
  756.         else if (MenuItem == mReplace)
  757.             {
  758.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  759.                     {
  760.                         DisableTextEditSelection(Window->ActiveTextEdit);
  761.                         Window->ActiveTextEdit = Window->FunctionEdit;
  762.                         EnableTextEditSelection(Window->ActiveTextEdit);
  763.                     }
  764.                 if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  765.                     {
  766.                         TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
  767.                             SYSTEMLINEFEED);
  768.                     }
  769.             }
  770.         else if (MenuItem == mReplaceAndFindAgain)
  771.             {
  772.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  773.                     {
  774.                         DisableTextEditSelection(Window->ActiveTextEdit);
  775.                         Window->ActiveTextEdit = Window->FunctionEdit;
  776.                         EnableTextEditSelection(Window->ActiveTextEdit);
  777.                     }
  778.                 if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  779.                     {
  780.                         TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
  781.                             SYSTEMLINEFEED);
  782.                         TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  783.                         TextEditShowSelection(Window->ActiveTextEdit);
  784.                     }
  785.             }
  786.         else if (MenuItem == mShowSelection)
  787.             {
  788.                 TextEditShowSelection(Window->ActiveTextEdit);
  789.             }
  790.         else if (MenuItem == mEnterSelection)
  791.             {
  792.                 char*                        NewString;
  793.  
  794.                 NewString = TextEditGetSelection(Window->ActiveTextEdit);
  795.                 if (NewString != NIL)
  796.                     {
  797.                         ReleasePtr(GlobalSearchString);
  798.                         GlobalSearchString = NewString;
  799.                     }
  800.             }
  801.         else
  802.             {
  803.                 EXECUTE(PRERR(AllowResume,"AlgoWaveTableWindowDoMenuCommand:  unknown menu command"));
  804.             }
  805.     }
  806.  
  807.  
  808. /* get a copy of the algorithmic wave table's name */
  809. char*                                AlgoWaveTableWindowGetNameCopy(AlgoWaveTableWindowRec* Window)
  810.     {
  811.         char*                            ReturnValue;
  812.  
  813.         CheckPtrExistence(Window);
  814.         ReturnValue = TextEditGetRawData(Window->NameEdit,"\x0a");
  815.         if (ReturnValue != NIL)
  816.             {
  817.                 SetTag(ReturnValue,"AlgoWaveTableNameCopy");
  818.             }
  819.         return ReturnValue;
  820.     }
  821.  
  822.  
  823. /* get a copy of the algorithmic wave table's formula */
  824. char*                                AlgoWaveTableWindowGetFormulaCopy(AlgoWaveTableWindowRec* Window)
  825.     {
  826.         char*                            ReturnValue;
  827.  
  828.         CheckPtrExistence(Window);
  829.         ReturnValue = TextEditGetRawData(Window->FunctionEdit,"\x0a");
  830.         if (ReturnValue != NIL)
  831.             {
  832.                 SetTag(ReturnValue,"AlgoWaveTableFormulaCopy");
  833.             }
  834.         return ReturnValue;
  835.     }
  836.  
  837.  
  838. /* get the number of bits used for this algorithmic wave table */
  839. NumBitsType                    AlgoWaveTableWindowGetNumBits(AlgoWaveTableWindowRec* Window)
  840.     {
  841.         CheckPtrExistence(Window);
  842.         if (GetIconButtonState(Window->Bits16Button))
  843.             {
  844.                 return eSample16bit;
  845.             }
  846.          else
  847.             {
  848.                 return eSample8bit;
  849.             }
  850.     }
  851.  
  852.  
  853. /* get the number of periods in the table */
  854. long                                AlgoWaveTableWindowGetNumTables(AlgoWaveTableWindowRec* Window)
  855.     {
  856.         long                            ReturnValue;
  857.         char*                            StringTemp;
  858.  
  859.         CheckPtrExistence(Window);
  860.         StringTemp = TextEditGetRawData(Window->NumTablesEdit,"\x0a");
  861.         if (StringTemp != NIL)
  862.             {
  863.                 ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
  864.                 ReleasePtr(StringTemp);
  865.             }
  866.          else
  867.             {
  868.                 ReturnValue = 0;
  869.             }
  870.         if (ReturnValue < 0)
  871.             {
  872.                 ReturnValue = 0;
  873.             }
  874.         return ReturnValue;
  875.     }
  876.  
  877.  
  878. /* get the number of frames in each period */
  879. long                                AlgoWaveTableWindowGetNumFrames(AlgoWaveTableWindowRec* Window)
  880.     {
  881.         long                            ReturnValue;
  882.         char*                            StringTemp;
  883.  
  884.         CheckPtrExistence(Window);
  885.         StringTemp = TextEditGetRawData(Window->NumFramesEdit,"\x0a");
  886.         if (StringTemp != NIL)
  887.             {
  888.                 ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
  889.                 ReleasePtr(StringTemp);
  890.             }
  891.          else
  892.             {
  893.                 ReturnValue = 0;
  894.             }
  895.         return ReturnValue;
  896.     }
  897.  
  898.  
  899. /* the name of the file has changed, so update the title bar of the window.  the */
  900. /* NewFilename is a non-null-terminated string which must be disposed by the caller */
  901. void                                AlgoWaveTableWindowGlobalNameChange(AlgoWaveTableWindowRec* Window,
  902.                                             char* NewFilename)
  903.     {
  904.         char*                            LocalNameCopy;
  905.  
  906.         CheckPtrExistence(Window);
  907.         CheckPtrExistence(NewFilename);
  908.         LocalNameCopy = AlgoWaveTableWindowGetNameCopy(Window);
  909.         if (LocalNameCopy != NIL)
  910.             {
  911.                 char*                            SeparatorString;
  912.  
  913.                 SeparatorString = StringToBlockCopy(":  ");
  914.                 if (SeparatorString != NIL)
  915.                     {
  916.                         char*                            LeftHalfOfString;
  917.  
  918.                         LeftHalfOfString = ConcatBlockCopy(NewFilename,SeparatorString);
  919.                         if (LeftHalfOfString != NIL)
  920.                             {
  921.                                 char*                            TotalString;
  922.  
  923.                                 TotalString = ConcatBlockCopy(LeftHalfOfString,LocalNameCopy);
  924.                                 if (TotalString != NIL)
  925.                                     {
  926.                                         char*                            NullTerminatedString;
  927.  
  928.                                         NullTerminatedString = BlockToStringCopy(TotalString);
  929.                                         if (NullTerminatedString != NIL)
  930.                                             {
  931.                                                 SetWindowName(Window->ScreenID,NullTerminatedString);
  932.                                                 ChangeItemName(Window->MyMenuItem,NullTerminatedString);
  933.                                                 ReleasePtr(NullTerminatedString);
  934.                                             }
  935.                                         ReleasePtr(TotalString);
  936.                                     }
  937.                                 ReleasePtr(LeftHalfOfString);
  938.                             }
  939.                         ReleasePtr(SeparatorString);
  940.                     }
  941.                 ReleasePtr(LocalNameCopy);
  942.             }
  943.     }
  944.  
  945.  
  946. /* reset the title bar name of the window even if the filename hasn't changed */
  947. void                                AlgoWaveTableWindowResetTitlebar(AlgoWaveTableWindowRec* Window)
  948.     {
  949.         char*                            DocumentName;
  950.  
  951.         CheckPtrExistence(Window);
  952.         DocumentName = GetCopyOfDocumentName(Window->MainWindow);
  953.         if (DocumentName != NIL)
  954.             {
  955.                 AlgoWaveTableWindowGlobalNameChange(Window,DocumentName);
  956.                 ReleasePtr(DocumentName);
  957.             }
  958.     }
  959.  
  960.  
  961. /* write back all modified data to the object */
  962. MyBoolean                        AlgoWaveTableWindowWritebackModifiedData(AlgoWaveTableWindowRec* Window)
  963.     {
  964.         MyBoolean                    SuccessFlag = True;
  965.  
  966.         CheckPtrExistence(Window);
  967.  
  968.         if (TextEditDoesItNeedToBeSaved(Window->NameEdit))
  969.             {
  970.                 char*                        String;
  971.  
  972.                 String = AlgoWaveTableWindowGetNameCopy(Window);
  973.                 if (String != NIL)
  974.                     {
  975.                         AlgoWaveTableObjectNewName(Window->AlgoWaveTableObject,String);
  976.                         TextEditHasBeenSaved(Window->NameEdit);
  977.                     }
  978.                  else
  979.                     {
  980.                         SuccessFlag = False;
  981.                     }
  982.             }
  983.  
  984.         if (TextEditDoesItNeedToBeSaved(Window->FunctionEdit))
  985.             {
  986.                 char*                        String;
  987.  
  988.                 String = AlgoWaveTableWindowGetFormulaCopy(Window);
  989.                 if (String != NIL)
  990.                     {
  991.                         AlgoWaveTableObjectNewFormula(Window->AlgoWaveTableObject,String);
  992.                         TextEditHasBeenSaved(Window->FunctionEdit);
  993.                     }
  994.                  else
  995.                     {
  996.                         SuccessFlag = False;
  997.                     }
  998.             }
  999.  
  1000.         if (TextEditDoesItNeedToBeSaved(Window->NumFramesEdit))
  1001.             {
  1002.                 AlgoWaveTableObjectPutNumFrames(Window->AlgoWaveTableObject,
  1003.                     AlgoWaveTableWindowGetNumFrames(Window));
  1004.                 TextEditHasBeenSaved(Window->NumFramesEdit);
  1005.             }
  1006.  
  1007.         if (TextEditDoesItNeedToBeSaved(Window->NumTablesEdit))
  1008.             {
  1009.                 AlgoWaveTableObjectPutNumTables(Window->AlgoWaveTableObject,
  1010.                     AlgoWaveTableWindowGetNumTables(Window));
  1011.                 TextEditHasBeenSaved(Window->NumTablesEdit);
  1012.             }
  1013.  
  1014.         if (Window->BitsChanged)
  1015.             {
  1016.                 AlgoWaveTableObjectPutNumBits(Window->AlgoWaveTableObject,
  1017.                     AlgoWaveTableWindowGetNumBits(Window));
  1018.                 Window->BitsChanged = False;
  1019.             }
  1020.  
  1021.         return SuccessFlag;
  1022.     }
  1023.